package dtoex

import (
	"go-admin-auth/app/dal"
	"go-admin-auth/app/models"
	"go-admin-auth/httpapi/enums"
)

type MenuQueryRes struct {
	Total int64          `json:"total" form:"total"`
	List  []models.TMenu `json:"list" form:"list"`
}

func (res *MenuQueryRes) Extend() *MenuQueryResEx {
	resEx := &MenuQueryResEx{
		Total: res.Total,
	}

	if len(res.List) == 0 {
		return resEx
	}

	resEx.List = ExtendMenuList(res.List)
	return resEx
}

type OperationQueryRes struct {
	Total int64               `json:"total" form:"total"`
	List  []models.TOperation `json:"list" form:"list"`
}

func (res *OperationQueryRes) Extend() *OperationQueryResEx {
	resEx := &OperationQueryResEx{
		Total: res.Total,
		List:  make([]TOperationEx, 0, len(res.List)),
	}

	if len(res.List) == 0 {
		return resEx
	}

	systemIdList := make([]int, 0)
	menuIdList := make([]int, 0)
	uidList := make([]int, 0)

	for _, v := range res.List {
		systemIdList = append(systemIdList, v.SystemId)
		menuIdList = append(menuIdList, v.ParentId, v.MenuId)
		uidList = append(uidList, v.CreateUid, v.UpdateUid)
	}

	systemMap, _ := dal.SubsystemDAO.GetMulti(systemIdList)
	menuMap, _ := dal.MenuDAO.GetMulti(menuIdList)
	userMap, _ := dal.UserDAO.GetMulti(uidList)

	for _, v := range res.List {
		tActionEx := TOperationEx{TOperation: v}

		tActionEx.SystemName = systemMap[v.SystemId].Name
		tActionEx.ParentName = menuMap[v.ParentId].Name
		tActionEx.MenuName = menuMap[v.MenuId].Name
		tActionEx.CreateUsername = userMap[v.CreateUid].RealName
		tActionEx.UpdateUsername = userMap[v.UpdateUid].RealName

		tActionEx.StatusDesc, _ = enums.StatusMap[v.Status]

		resEx.List = append(resEx.List, tActionEx)
	}

	return resEx
}

type OrganizationQueryRes struct {
	Total int64                  `json:"total" form:"total"`
	List  []models.TOrganization `json:"list" form:"list"`
}

func (res *OrganizationQueryRes) Extend() *OrganizationQueryResEx {
	resEx := &OrganizationQueryResEx{
		Total: res.Total,
		List:  make([]TOrganizationEx, 0, len(res.List)),
	}

	if len(res.List) == 0 {
		return resEx
	}

	orgIdList := make([]int, 0)
	uidList := make([]int, 0)

	for _, v := range res.List {
		orgIdList = append(orgIdList, v.ParentId)
		uidList = append(uidList, v.CreateUid, v.UpdateUid)
	}

	orgMap, _ := dal.OrganizationDAO.GetMulti(orgIdList)
	userMap, _ := dal.UserDAO.GetMulti(uidList)

	for _, v := range res.List {
		tActionEx := TOrganizationEx{TOrganization: v}

		tActionEx.ParentName = orgMap[v.ParentId].Name
		tActionEx.CreateUsername = userMap[v.CreateUid].RealName
		tActionEx.UpdateUsername = userMap[v.UpdateUid].RealName

		tActionEx.StatusDesc, _ = enums.StatusMap[v.Status]

		resEx.List = append(resEx.List, tActionEx)
	}

	return resEx
}

type RoleQueryRes struct {
	Total int64          `json:"total" form:"total"`
	List  []models.TRole `json:"list" form:"list"`
}

func (res *RoleQueryRes) Extend() *RoleQueryResEx {
	resEx := &RoleQueryResEx{
		Total: res.Total,
		List:  make([]TRoleEx, 0, len(res.List)),
	}

	if len(res.List) == 0 {
		return resEx
	}

	uidList := make([]int, 0)

	for _, v := range res.List {
		uidList = append(uidList, v.CreateUid, v.UpdateUid)
	}

	userMap, _ := dal.UserDAO.GetMulti(uidList)

	for _, v := range res.List {
		tActionEx := TRoleEx{TRole: v}

		tActionEx.CreateUsername = userMap[v.CreateUid].RealName
		tActionEx.UpdateUsername = userMap[v.UpdateUid].RealName

		tActionEx.StatusDesc, _ = enums.StatusMap[v.Status]

		resEx.List = append(resEx.List, tActionEx)
	}

	return resEx
}

type RoleMenuQueryRes struct {
	Total int64              `json:"total" form:"total"`
	List  []models.TRoleMenu `json:"list" form:"list"`
}

func (res *RoleMenuQueryRes) Extend() *RoleMenuQueryResEx {
	resEx := &RoleMenuQueryResEx{
		Total: res.Total,
		List:  make([]TRoleMenuEx, 0, len(res.List)),
	}

	if len(res.List) == 0 {
		return resEx
	}

	roleIdList := make([]int, 0)
	menuIdList := make([]int, 0)
	systemIdList := make([]int, 0)

	for _, v := range res.List {
		systemIdList = append(systemIdList, v.SystemId)
		roleIdList = append(roleIdList, v.RoleId)
		menuIdList = append(menuIdList, v.MenuId)
	}

	systemMap, _ := dal.SubsystemDAO.GetMulti(systemIdList)
	menuMap, _ := dal.MenuDAO.GetMulti(menuIdList)
	roleMap, _ := dal.UserDAO.GetMulti(roleIdList)

	for _, v := range res.List {
		tActionEx := TRoleMenuEx{TRoleMenu: v}

		tActionEx.SystemName = systemMap[v.SystemId].Name
		tActionEx.MenuName = menuMap[v.MenuId].Name
		tActionEx.RoleName = roleMap[v.RoleId].Name

		resEx.List = append(resEx.List, tActionEx)
	}

	return resEx
}

type SubsystemQueryRes struct {
	Total int64               `json:"total" form:"total"`
	List  []models.TSubsystem `json:"list" form:"list"`
}

func (res *SubsystemQueryRes) Extend() *SubsystemQueryResEx {
	resEx := &SubsystemQueryResEx{
		Total: res.Total,
		List:  make([]TSubsystemEx, 0, len(res.List)),
	}

	if len(res.List) == 0 {
		return resEx
	}

	uidList := make([]int, 0)

	for _, v := range res.List {
		uidList = append(uidList, v.CreateUid, v.UpdateUid)
	}

	userMap, _ := dal.UserDAO.GetMulti(uidList)

	for _, v := range res.List {
		tActionEx := TSubsystemEx{TSubsystem: v}

		tActionEx.CreateUsername = userMap[v.CreateUid].RealName
		tActionEx.UpdateUsername = userMap[v.UpdateUid].RealName

		resEx.List = append(resEx.List, tActionEx)
	}

	return resEx
}

type UserQueryRes struct {
	Total int64          `json:"total" form:"total"`
	List  []models.TUser `json:"list" form:"list"`
}

func (res *UserQueryRes) Extend() *UserQueryResEx {
	resEx := &UserQueryResEx{
		Total: res.Total,
		List:  make([]TUserEx, 0, len(res.List)),
	}

	if len(res.List) == 0 {
		return resEx
	}

	uidList := make([]int, 0)
	orgIdList := make([]int, 0)
	for _, v := range res.List {
		uidList = append(uidList, v.CreateUid, v.UpdateUid)
		orgIdList = append(orgIdList, v.OrgId)
	}

	userMap, _ := dal.UserDAO.GetMulti(uidList)

	for _, v := range res.List {
		tActionEx := TUserEx{TUser: v}

		tActionEx.CreateUsername = userMap[v.CreateUid].RealName
		tActionEx.UpdateUsername = userMap[v.UpdateUid].RealName

		tActionEx.IsRootDesc, _ = enums.IsRootMap[v.IsRoot]

		resEx.List = append(resEx.List, tActionEx)
	}

	return resEx
}
